package cn.infozr.api.client;

import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
import java.text.SimpleDateFormat;
import java.util.Date;

import cn.infozr.api.util.MD5Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 新增药品信息上传接口客户端
 * 用于测试 https://IP:端口/ygydapi/v1/uploadDrugInfo 接口
 */
public class DrugInfoUploadApiClient extends BaseClient {
    

    
    /**
     * 新增药品信息数据项
     */
    public static class DrugInfoItem {
        private String id;              // 企业侧ERP系统本地的唯一id
        private String yppzwh;          // 药品批准文号
        private String ypssxkcyrmc;     // 上市许可持有人名称
        private String ypscqymc;        // 药品生产单位名称
        private String yptymc;          // 药品通用名称
        private String ypspmc;          // 药品商品名称
        private String bzgg;            // 包装规格
        private String zjgg;            // 制剂规格
        private String jx;              // 剂型
        private String ypzcfl;          // 药品注册分类
        private String cfybs;           // 处方药标识
        private String ybmlyp;          // 是否医保名录药品
        private String gchjkyp;         // 国产或进口药品标识
        private String ypfl;            // 药品分类
        private Integer ypyxq;          // 药品有效期
        private String ypyxqdw;         // 药品有效期单位

        private String yptxm;//	是	药品条形码
        private String  ypbsm;//	是	药品追溯码前7位
        private String gjybbm;//	是	国家医保编码
        private String ypcf;//	是	药品成份
        private String yyjj;//	是	用药禁忌
        private String tsrq;//	是	特殊人群
        private String gnzz;//	是	功能主治
        private String yfyl;//	是	用法用量
        private String ypxz;//	是	药品性状
        private String blfs;//	是	不良反应
        private String cctj;//	是	储藏条件
        private String zysx;//	是	注意事项
        private String xhzy;//	是	相互作用
        private String yptp;//	是	药品图片，多个图片地址用英文逗号隔开（http或https开头的互联网访问地址）
        
        // Getters and Setters
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        
        public String getYppzwh() { return yppzwh; }
        public void setYppzwh(String yppzwh) { this.yppzwh = yppzwh; }
        
        public String getYpssxkcyrmc() { return ypssxkcyrmc; }
        public void setYpssxkcyrmc(String ypssxkcyrmc) { this.ypssxkcyrmc = ypssxkcyrmc; }
        
        public String getYpscqymc() { return ypscqymc; }
        public void setYpscqymc(String ypscqymc) { this.ypscqymc = ypscqymc; }
        
        public String getYptymc() { return yptymc; }
        public void setYptymc(String yptymc) { this.yptymc = yptymc; }
        
        public String getYpspmc() { return ypspmc; }
        public void setYpspmc(String ypspmc) { this.ypspmc = ypspmc; }
        
        public String getBzgg() { return bzgg; }
        public void setBzgg(String bzgg) { this.bzgg = bzgg; }
        
        public String getZjgg() { return zjgg; }
        public void setZjgg(String zjgg) { this.zjgg = zjgg; }
        
        public String getJx() { return jx; }
        public void setJx(String jx) { this.jx = jx; }
        
        public String getYpzcfl() { return ypzcfl; }
        public void setYpzcfl(String ypzcfl) { this.ypzcfl = ypzcfl; }
        
        public String getCfybs() { return cfybs; }
        public void setCfybs(String cfybs) { this.cfybs = cfybs; }
        
        public String getYbmlyp() { return ybmlyp; }
        public void setYbmlyp(String ybmlyp) { this.ybmlyp = ybmlyp; }
        
        public String getGchjkyp() { return gchjkyp; }
        public void setGchjkyp(String gchjkyp) { this.gchjkyp = gchjkyp; }
        
        public String getYpfl() { return ypfl; }
        public void setYpfl(String ypfl) { this.ypfl = ypfl; }
        
        public Integer getYpyxq() { return ypyxq; }
        public void setYpyxq(Integer ypyxq) { this.ypyxq = ypyxq; }
        
        public String getYpyxqdw() { return ypyxqdw; }
        public void setYpyxqdw(String ypyxqdw) { this.ypyxqdw = ypyxqdw; }

        public String getYptxm() {
            return yptxm;
        }

        public void setYptxm(String yptxm) {
            this.yptxm = yptxm;
        }

        public String getYpbsm() {
            return ypbsm;
        }

        public void setYpbsm(String ypbsm) {
            this.ypbsm = ypbsm;
        }

        public String getGjybbm() {
            return gjybbm;
        }

        public void setGjybbm(String gjybbm) {
            this.gjybbm = gjybbm;
        }

        public String getYpcf() {
            return ypcf;
        }

        public void setYpcf(String ypcf) {
            this.ypcf = ypcf;
        }

        public String getYyjj() {
            return yyjj;
        }

        public void setYyjj(String yyjj) {
            this.yyjj = yyjj;
        }

        public String getTsrq() {
            return tsrq;
        }

        public void setTsrq(String tsrq) {
            this.tsrq = tsrq;
        }

        public String getGnzz() {
            return gnzz;
        }

        public void setGnzz(String gnzz) {
            this.gnzz = gnzz;
        }

        public String getYfyl() {
            return yfyl;
        }

        public void setYfyl(String yfyl) {
            this.yfyl = yfyl;
        }

        public String getYpxz() {
            return ypxz;
        }

        public void setYpxz(String ypxz) {
            this.ypxz = ypxz;
        }

        public String getBlfs() {
            return blfs;
        }

        public void setBlfs(String blfs) {
            this.blfs = blfs;
        }

        public String getCctj() {
            return cctj;
        }

        public void setCctj(String cctj) {
            this.cctj = cctj;
        }

        public String getZysx() {
            return zysx;
        }

        public void setZysx(String zysx) {
            this.zysx = zysx;
        }

        public String getXhzy() {
            return xhzy;
        }

        public void setXhzy(String xhzy) {
            this.xhzy = xhzy;
        }

        public String getYptp() {
            return yptp;
        }

        public void setYptp(String yptp) {
            this.yptp = yptp;
        }
    }
    
    /**
     * 新增药品信息上传请求参数类
     */
    public static class DrugInfoUploadRequest {
        private String appId;
        private String timestamp;
        private String reqId;
        private String uscc;
       // private List<DrugInfoItem> data;
        private String data;
        private String sign;
        
        // 构造函数
        public DrugInfoUploadRequest() {
            this.timestamp = String.valueOf(System.currentTimeMillis());
            //this.data = new ArrayList<>();
        }
        
        // Getters and Setters
        public String getAppId() { return appId; }
        public void setAppId(String appId) { this.appId = appId; }
        
        public String getTimestamp() { return timestamp; }
        public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
        
        public String getReqId() { return reqId; }
        public void setReqId(String reqId) { this.reqId = reqId; }
        
        public String getUscc() { return uscc; }
        public void setUscc(String uscc) { this.uscc = uscc; }
        
        public String getData() { return data; }
        public void setData(String data) { this.data = data; }
        
        public String getSign() { return sign; }
        public void setSign(String sign) { this.sign = sign; }
    }
    
    /**
     * 上传药品信息
     * @param uscc 药店统一社会信用代码
     * @param data 药品信息列表
     * @return 接口响应结果
     * @throws Exception 网络或解析异常
     */
    public String uploadDrugInfo(String uscc, List<DrugInfoItem> data) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String dataJson = objectMapper.writeValueAsString(data);

        // 构造请求参数
        DrugInfoUploadRequest request = new DrugInfoUploadRequest();
        request.setAppId(APP_ID);
        request.setUscc(uscc);
        request.setData(dataJson);
        request.setReqId(UUID.randomUUID().toString());
        
        // 生成签名
        java.util.TreeMap<String, String> signParams = new java.util.TreeMap<>();
        signParams.put("appId", request.getAppId());
        signParams.put("timestamp", request.getTimestamp());
        signParams.put("reqId", request.getReqId());
        signParams.put("uscc", request.getUscc());
        signParams.put("data", dataJson);

        String sign = cn.infozr.api.util.SM3SignatureUtil.generateSignature(signParams, SECRET_KEY);
        request.setSign(sign);
        
        // 发送POST请求
        return sendPostRequest(DRUG_INFO_API_URL, request);
    }
    
    /**
     * 发送POST请求
     * @param url 请求地址
     * @param request 请求参数对象
     * @return 响应结果
     * @throws Exception 网络异常
     */
    private String sendPostRequest(String url, DrugInfoUploadRequest request) throws Exception {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // 设置请求方法和请求头
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");
        con.setDoOutput(true);

        // 序列化请求参数，过滤空值
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String jsonInputString = objectMapper.writeValueAsString(request);
        System.out.println("请求参数: " + jsonInputString);
        
        // 发送请求
        try(OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        // 读取响应
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getInputStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine = null;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                return response.toString();
            }
        } else {
            // 读取错误响应
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getErrorStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine = null;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                System.err.println("错误响应: " + response.toString());
                return "{\"code\":" + responseCode + ",\"msg\":\"请求失败\"}";
            }
        }
    }
    
    /**
     * 解析并打印上传结果
     * @param jsonResponse JSON响应字符串
     * @throws Exception 解析异常
     */
    public void parseAndPrintUploadResult(String jsonResponse) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        com.fasterxml.jackson.databind.JsonNode rootNode = objectMapper.readTree(jsonResponse);
        
        System.out.println("接口响应:");
        System.out.println("状态码: " + (rootNode.has("code") ? rootNode.get("code").asText() : "无"));
        System.out.println("消息提示: " + (rootNode.has("msg") ? rootNode.get("msg").asText() : "无"));
        System.out.println("请求ID: " + (rootNode.has("reqId") ? rootNode.get("reqId").asText() : "无"));
        
        // 打印数据部分
        if (rootNode.has("data") && !rootNode.get("data").isNull()) {
            System.out.println("返回数据:");
            com.fasterxml.jackson.databind.JsonNode dataNode = rootNode.get("data");
            if (dataNode.isArray()) {
                for (com.fasterxml.jackson.databind.JsonNode item : dataNode) {
                    System.out.println("  药品唯一标识码: " + (item.has("ypwybsm") ? item.get("ypwybsm").asText() : "无"));
                    System.out.println("  本地唯一ID: " + (item.has("id") ? item.get("id").asText() : "无"));
                    System.out.println("  ----------");
                }
            }
        }
    }
    
    /**
     * 主方法 - 测试接口调用
     */
    public static void main(String[] args) {
        try {
            DrugInfoUploadApiClient client = new DrugInfoUploadApiClient();
            
            // 构造测试数据
            List<DrugInfoItem> data = new ArrayList<>();

            for(int i = 0; i < 10; i++) {
                DrugInfoItem item1 = new DrugInfoItem();
                item1.setId("local_001"+i);//本地系统的id
                item1.setYppzwh("国药准字H2021"+i);
                item1.setYpssxkcyrmc("某某药业有限公司");
                item1.setYpscqymc("某某制药厂");
                item1.setYptymc("阿司匹林肠溶片");
                item1.setYpspmc("阿司匹林肠溶片");
                item1.setBzgg("100片/瓶");
                item1.setZjgg("100mg");
                item1.setJx("01");
                item1.setYpzcfl("2");
                item1.setCfybs("1"); // 处方药
                item1.setYbmlyp("1"); // 医保药品
                item1.setGchjkyp("1"); // 国产药品
                item1.setYpfl("14");
                item1.setYpyxq(24);
                item1.setYpyxqdw("M"); // 月
                item1.setYptxm("6952145212541");
                item1.setYpbsm("8521851");
                item1.setGjybbm("ZS20230001");
                item1.setYpcf("阿司匹林肠溶片");
                item1.setYyjj("1.不与阿司匹林、阿草及阿草基类药品同时使用。2.不与阿司匹林、阿草及阿草基类药品同时使用。3.不与阿司匹林、阿草及阿草基类药品同时使用。4.不与阿司匹林、阿草及阿草基类药品同时使用。");
                item1.setTsrq("孕妇");
                item1.setGnzz("消炎");
                item1.setYfyl("一次一片1日3次");
                item1.setYpxz("本品为");
                item1.setBlfs("");//不良反应
                item1.setCctj("常温储存");
                item1.setZysx("不可与混用");//注意事项
                item1.setXhzy("1");//相互作用
                //药品图片，多个图片地址用英文逗号隔开（http或https开头的互联网访问地址）
                item1.setYptp("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");
                data.add(item1);
            }
            DrugInfoItem item2 = new DrugInfoItem();
            item2.setId("local_003");//本地系统的id
            item2.setYppzwh("国药准字H2021000442");
            item2.setYpssxkcyrmc("某某药业有限公司");
            item2.setYpscqymc("某某制药厂");
            item2.setYptymc("布洛芬缓释胶囊");
            item2.setYpspmc("布洛芬缓释胶囊");
            item2.setBzgg("20粒/盒");
            item2.setZjgg("300mg");
            item2.setJx("测试剂型");
            item2.setYpzcfl("2");
            item2.setCfybs("2"); // OTC
            item2.setYbmlyp("2"); // 非医保药品
            item2.setGchjkyp("1"); // 国产药品
            item2.setYpfl("03");
            item2.setYpyxq(36);
            item2.setYpyxqdw("M"); // 月

            item2.setYptxm("455555555588844");
            data.add(item2);


            // 测试调用接口
            String result = client.uploadDrugInfo(uscc, data);
            //todo 获取到返回数据后，更新本地数据库将商品信息与药品唯一标识码关联
            // 解析并打印结果
            client.parseAndPrintUploadResult(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}